﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MShop.Core.DataAccess;
using MShop.Core.Domain;
using MShop.Core;
using MShop.Core.Epay.Ali;
using MShop.Core.Util;
using System.Collections.Specialized;
using MShop.Core.Epay.TenPay;
using System.Collections;
using System.Text;

namespace MShop.Web.Controllers
{
    public class PayController : ControllerBase
    {

        private readonly IProductDao _ProductDao;
        private readonly IItemCatDao _ItemCatDao;    
        private readonly ICartItemDao _CommonDao;
        private readonly IPayDao _PayDao;
        private readonly ICommonDao<Distribution> _CommonDao2;
        private readonly IShopContext _ShopContext;
        private readonly IAreaGroupDao _AreaGroupDao;
        private readonly ICommonDao<ShopUsersAddress> _CommonDao3;
        private readonly ITradeDao _TradeDao;
        private readonly IPayPluginDao _PayPluginDao;
        private readonly ICommonDao<ShopUsersCryptography> _ShopUsersCryptographyDao;
        public PayController(IProductDao productDao, IItemCatDao itemcatdao, IBrandDao brandDao, ISupplierDao supplierDao,
            ICartItemDao commonDao, IShopContext shopContext, IPayDao payDao, ICommonDao<Distribution> commonDao2,IAreaGroupDao areaGroupDao,
            ICommonDao<ShopUsersAddress> commonDao3, ITradeDao tradeDao, IPayPluginDao payPluginDao, ICommonDao<ShopUsersCryptography> shopUsersCryptographyDao
            )
        { 
            _ItemCatDao = itemcatdao;
            _ProductDao = productDao;       
            _CommonDao = commonDao;
            _ShopContext = shopContext;
            _PayDao = payDao;
            _CommonDao2 = commonDao2;
            _AreaGroupDao = areaGroupDao;
            _CommonDao3=commonDao3;
            _TradeDao = tradeDao;
            _PayPluginDao = payPluginDao;
            _ShopUsersCryptographyDao = shopUsersCryptographyDao;
        }

        public ActionResult AutoChinaBankReceive()
        {
            string v_oid = Request["v_oid"];
            string v_pstatus = Request["v_pstatus"];
            string v_pstring = Request["v_pstring"];
            string v_pmode = Request["v_pmode"];
            string v_md5str = Request["v_md5str"];
            string v_amount = Request["v_amount"];
            string v_moneytype = Request["v_moneytype"];
            string remark1 = Request["remark1"];
            string remark2 = Request["remark2"];


            Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == v_oid);
            Pay pay = _PayDao.GetById(typeof(ChinaBankPayModel));
            ChinaBankPayModel chinaBank = (ChinaBankPayModel)pay.PayModel;
            string key = chinaBank.SecretKey;
            string str = v_oid + v_pstatus + v_amount + v_moneytype + key;
            str = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5").ToUpper();

            if (str == v_md5str)
            {
                //Response.Write("ok"); //通知网银服务器验证通过，停止发送

                if (v_pstatus.Equals("20"))
                {
                    if (trade.TradeStatus != (int)TradeStatus.买家已付款)
                    {
                        trade.TradeStatus = (int)TradeStatus.买家已付款;
                        trade.Modified = DateTime.Now;
                        trade.PayTime = DateTime.Now;
                        decimal payment = Convert.ToDecimal(v_amount);
                        trade.Payment = payment;
                        //更改用户积分
                        var usercrypt = _ShopUsersCryptographyDao.Find(x => x.UserId == trade.UserId).First();
                        usercrypt.TotalFee += trade.Payment;
                        usercrypt.Point += trade.TotalPoint;
                        _TradeDao.SaveChanges(); ;
                    }
                    //支付成功
                    //商户系统的逻辑处理（例如判断金额，判断支付状态，更新订单状态等等）.......
                    return View("ok");

                }
            }
            else
            {
                return Content("error");  //验证失败，请求重发
            }
            return Content("error");
        }

        /// <summary>
        /// 商户自定义返回接收支付结果的页面
        /// </summary>
        /// <returns></returns>
        public ActionResult ChinaBankReceive()
        {	// MD5密钥要跟订单提交页相同，如Send.asp里的 key = "test" ,修改""号内 test 为您的密钥
            string key = "";	// 如果您还没有设置MD5密钥请登陆我们为您提供商户后台，地址：https://merchant3.chinabank.com.cn/
            // 登陆后在上面的导航栏里可能找到“资料管理”，在资料管理的二级导航栏里有“MD5密钥设置”
            // 建议您设置一个16位以上的密钥或更高，密钥最多64位，但设置16位已经足够了			

           string v_oid = Request["v_oid"];
           string v_pstatus = Request["v_pstatus"];
           string v_pstring = Request["v_pstring"];
           string v_pmode = Request["v_pmode"];
           string v_md5str = Request["v_md5str"];
           string v_amount = Request["v_amount"];
           string v_moneytype = Request["v_moneytype"];
           string remark1 = Request["remark1"];
           string remark2 = Request["remark2"];


           Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == v_oid);
           Pay pay = _PayDao.GetById(typeof(ChinaBankPayModel));
           ChinaBankPayModel chinaBank = (ChinaBankPayModel)pay.PayModel;
           key = chinaBank.SecretKey;
           string str = v_oid + v_pstatus + v_amount + v_moneytype + key;
           str = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(str, "md5").ToUpper();

            if (str == v_md5str)
            {
                //Response.Write("ok"); //通知网银服务器验证通过，停止发送

                if (v_pstatus.Equals("20"))
                {
                    if (trade.TradeStatus != (int)TradeStatus.买家已付款)
                    {
                        trade.TradeStatus = (int)TradeStatus.买家已付款;
                        trade.Modified = DateTime.Now;
                        trade.PayTime = DateTime.Now;
                        decimal payment = Convert.ToDecimal(v_amount);
                        trade.Payment = payment;
                        //更改用户积分
                        var usercrypt = _ShopUsersCryptographyDao.Find(x => x.UserId == trade.UserId).First();
                        usercrypt.TotalFee += trade.Payment;
                        usercrypt.Point += trade.TotalPoint;
                        _TradeDao.SaveChanges();                      ;
                    }
                    //支付成功
                    //商户系统的逻辑处理（例如判断金额，判断支付状态，更新订单状态等等）.......
                    return View(trade);
                   
                }
            }
            else
            {
                return Content("验证失败，请求重发,请联系管理员。");  //验证失败，请求重发
            }
            return Content("验证失败，请联系管理员。");
        }

        public ActionResult ChinaBankSend(string tid)
        {
            //http://localhost:6723/Trade/success?token=v3khfp0zkkjrd5gv2n21rafo&tradeid=20101228120100160&paytype=8
            Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == tid);
            Pay pay = _PayDao.GetById(typeof(ChinaBankPayModel));
            ChinaBankPayModel chinaBank = (ChinaBankPayModel)pay.PayModel;
           
           
           

            string v_url = string.Concat(_ShopContext.Settings.WebSiteUrl,"/","pay/chinabankreceive"); // 商户自定义返回接收支付结果的页面
            ViewData["v_url"] = v_url;
            // MD5密钥要跟订单提交页相同，如Send.asp里的 key = "test" ,修改""号内 test 为您的密钥
            string key = chinaBank.SecretKey;		 // 如果您还没有设置MD5密钥请登陆我们为您提供商户后台，地址：https://merchant3.chinabank.com.cn/
            ViewData["key"] = key;
            // 登陆后在上面的导航栏里可能找到“资料管理”，在资料管理的二级导航栏里有“MD5密钥设置”
            // 建议您设置一个16位以上的密钥或更高，密钥最多64位，但设置16位已经足够了

           //v_mid 商户号，这里为测试商户号20000400，替换为自己的商户号即可
            string v_mid= chinaBank.Code ;
            ViewData["v_mid"] = v_mid;

            string v_oid = trade.TradeId;//订单号 

            string v_amount = trade.TotalSum.ToString();//订单总金额（元）：

            string v_moneytype="CNY";

            ViewData["v_moneytype"] = v_moneytype; //RMB

            string text = v_amount + v_moneytype + v_oid + v_mid + v_url + key; // 拼凑加密串

            string v_md5info = System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(text, "md5").ToUpper();
                     
            ViewData["v_md5info"]= v_md5info;

            ViewData["v_rcvemail"] = "";
            
            return View(trade);
        }

        public ActionResult TenPayShowUrl(string tid)
        { 
            Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == tid);
            return View(trade);
        }
        public ActionResult TenPayReturn()
        {
            Pay pay = _PayDao.GetById(typeof(TenPayModel));
            TenPayModel tenPay=(TenPayModel)pay.PayModel;
            //密钥
            string key = tenPay.SecretKey;

            //创建PayResponseHandler实例
            PayResponseHandler resHandler = new PayResponseHandler(System.Web.HttpContext.Current);

            resHandler.setKey(key);

            //判断签名
            if (resHandler.isTenpaySign())
            {
                //交易单号
                string transaction_id = resHandler.getParameter("transaction_id");

                //金额金额,以分为单位
                string total_fee = resHandler.getParameter("total_fee");

                //支付结果
                string pay_result = resHandler.getParameter("pay_result");

                string sp_billno=resHandler.getParameter("sp_billno");

                if ("0".Equals(pay_result))//支付成功
                {
                    //------------------------------
                    //处理业务开始
                    //------------------------------ 


                    Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == sp_billno);

                    if (trade.TradeStatus != (int)TradeStatus.买家已付款)
                    {
                        trade.TradeStatus = (int)TradeStatus.买家已付款;
                        trade.Modified = DateTime.Now;
                        trade.PayTime = DateTime.Now;
                        decimal payment = Convert.ToDecimal(total_fee) / 100;
                        trade.Payment = payment;
                        //更改用户积分
                        var usercrypt = _ShopUsersCryptographyDao.Find(x => x.UserId == trade.UserId).First();
                        usercrypt.TotalFee += trade.Payment;
                        usercrypt.Point += trade.TotalPoint;
                        _TradeDao.SaveChanges();
                        ViewData["showurl"] = "/pay/TenPayShowUrl?tid=" + trade.TradeId;
                        return View(trade);
                    }
                    else
                    {
                         
                            return Content("你已经付过款，请不要再次付款。");
                        
                    }

                    //注意交易单不要重复处理
                    //注意判断返回金额

                    //------------------------------
                    //处理业务完毕
                    //------------------------------

                    //调用doShow, 打印meta值跟js代码,告诉财付通处理成功,并在用户浏览器显示$show页面.
                    //resHandler.doShow("http://localhost/tenpayApp/show.aspx");
                }
                else
                {
                    //当做不成功处理
                    return Content("财付通支付失败,请检查网络");
                }

            }
            else
            {
                return Content("认证签名失败,请检查网络");
                //string debugInfo = resHandler.getDebugInfo();
                //Response.Write("<br/>debugInfo:" + debugInfo);
            }           

        }
        public ActionResult TenPay(string tid)
        {
            Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == tid);
            if (trade.TradeStatus == (int)TradeStatus.买家已付款)
            {
                return Content("你已经付过款，请不要再次付款。");
            }

            Pay pay = _PayDao.GetById(typeof(TenPayModel));
            TenPayModel tenPay=(TenPayModel)pay.PayModel;
            //商户号
            string bargainor_id = tenPay.Code;

            //密钥
            string key = tenPay.SecretKey;

            //当前时间 yyyyMMdd
            string date = DateTime.Now.ToString("yyyyMMdd");

            //生成订单10位序列号，此处用时间和随机数生成，商户根据自己调整，保证唯一
            string strReq = "" + DateTime.Now.ToString("HHmmss") + TenpayUtil.BuildRandomStr(4);

            //商户订单号，不超过32位，财付通只做记录，不保证唯一性
            string sp_billno = tid;

            //财付通订单号，10位商户号+8位日期+10位序列号，需保证全局唯一
            string transaction_id = bargainor_id + date + strReq;

           //商品金额,以分为单位
            string totalfee = ((int)(trade.TotalSum * 100)).ToString();

            string return_url = string.Concat(_ShopContext.Settings.WebSiteUrl, "/Pay/TenPayReturn");

            //创建PayRequestHandler实例
            PayRequestHandler reqHandler = new PayRequestHandler(System.Web.HttpContext.Current);

            //设置密钥
            reqHandler.setKey(key);

            //初始化
            reqHandler.init();

            //-----------------------------
            //设置支付参数
            //-----------------------------
            reqHandler.setParameter("cs", "utf-8");		
            reqHandler.setParameter("bargainor_id", bargainor_id);			//商户号
            reqHandler.setParameter("sp_billno", sp_billno);				//商家订单号
            reqHandler.setParameter("transaction_id", transaction_id);		//财付通交易单号
            reqHandler.setParameter("return_url", return_url);				//支付通知url
            reqHandler.setParameter("desc", (string.Concat("订单号：",transaction_id)));	//商品名称
            reqHandler.setParameter("total_fee", totalfee);	     			//商品金额,以分为单位
            
            reqHandler.setParameter("spbill_create_ip", UrlUtil.GetRealIp());

            StringBuilder sb = new StringBuilder();


            //用户ip,测试环境时不要加这个ip参数，正式环境再加此参数
            //reqHandler.setParameter("spbill_create_ip",Request.UserHostAddress);

            //获取请求带参数的url
            string requestUrl = reqHandler.getRequestURL();
            sb.Append("<html><head><title>正在转向腾讯财付通交易平台.....</title></head><body>");
            sb.Append("如果你的浏览器没有反应，请点击<a target=\"_blank\" href=\"" + requestUrl + "\">" + "财付通支付。" + "</a>");
            sb.Append("<script>window.setTimeout(\"document.location.href='"+ requestUrl+"'\",2000);</script>");
            sb.Append("</body></html>");
           // Response.Write(a_link);
            
            return Content(sb.ToString());
            //post实现方式
            //reqHandler.getRequestURL();
            //StringBuilder sb = new StringBuilder();
            //sb.Append("<html><head><title>正在转向腾讯财付通交易平台.....</title></head><body>");
            //sb.Append("<form method=\"post\" name=\"tenpay\" action=\"" + reqHandler.getGateUrl() + "\" >\n");
            //Hashtable ht = reqHandler.getAllParameters();
            //foreach(DictionaryEntry de in ht) 
            //{
            //    sb.Append("<input type=\"hidden\" name=\"" + de.Key + "\" value=\"" + de.Value + "\" >\n");
            //}
            //sb.Append("<input type=\"submit\" value=\"财付通支付\" >\n</form>\n");
            //sb.Append("<script>window.setTimeout(\"document.forms['tenpay'].submit()\",2000);</script>");
            //sb.Append("</body></html>");
            //return Content(sb.ToString());
            //http://localhost:6723/Trade/success?token=h2jfivaszumuoobneqwg34xf&tradeid=20101227120308368&paytype=16
            //获取debug信息
            //string debuginfo = reqHandler.getDebugInfo();
            //Response.Write("<br/>" + debuginfo + "<br/>");

            //重定向到财付通支付
           // reqHandler.doSend();
        }

        public ActionResult AliPay(string tid)
        {
            Trade trade = _TradeDao.FirstOrDefault(x=>x.TradeId==tid);
            if (trade.TradeStatus == (int)TradeStatus.买家已付款)
            {
                return Content("你已经付过款，请不要再次付款。");
            }

            Pay pay = _PayDao.GetById(typeof(AliPayasSurePayModel));
            AlipayConfig con = new AlipayConfig(_ShopContext, (AliPayasSurePayModel)pay.PayModel);
            //Response.Write(con.Key);
            //Response.Write(con.Partner);
            //Response.Write(con.Input_charset);
            //Response.End();
            string partner = con.Partner;
            string key = con.Key;
            string seller_email = con.Seller_email;
            string input_charset = con.Input_charset;
            string notify_url = con.Notify_url;
            string return_url = con.Return_url;
            string show_url = con.Show_url;
            string sign_type = con.Sign_type;

            ////////////////////////////////////////////////////////////////////////////////////////////////////

            ///////////////////////以下参数是需要通过下单时的订单数据传入进来获得////////////////////////////////
            //必填参数
            string out_trade_no = trade.TradeId;  //请与贵网站订单系统中的唯一订单号匹配
            string subject = trade.Subject;                        //订单名称，显示在支付宝收银台里的“商品名称”里，显示在支付宝的交易管理的“商品名称”的列表里。
            string body = trade.Body;                         //订单描述、订单详细、订单备注，显示在支付宝收银台里的“商品描述”里
            string price = trade.TotalFee.ToString();               //订单总金额，显示在支付宝收银台里的“商品单价”里

            string logistics_fee = trade.PostFee.ToString();  				//物流费用，即运费。
            //trade.DistributionId == 1 ==快递
            string logistics_type = trade.DistributionId == 1 ? "EXPRESS" : "EMS";	  //物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
            string logistics_payment = "BUYER_PAY";            		    	//物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

            string quantity = "1";              							//商品数量，建议默认为1，不改变值，把一次交易看成是一次下订单而非购买一件商品。

            //扩展参数——买家收货信息（推荐作为必填）
            //该功能作用在于买家已经在商户网站的下单流程中填过一次收货信息，而不需要买家在支付宝的付款流程中再次填写收货信息。
            //若要使用该功能，请至少保证receive_name、receive_address有值
            //收货信息格式请严格按照姓名、地址、邮编、电话、手机的格式填写
            string receive_name = trade.ReceiverName;	                    //收货人姓名，如：张三
            string receive_address = trade.Location;			                //收货人地址，如：XX省XXX市XXX区XXX路XXX小区XXX栋XXX单元XXX号
            string receive_zip = trade.PostCode;              			    //收货人邮编，如：123456
            string receive_phone = string.IsNullOrEmpty(trade.Tel)?trade.Mobile:trade.Tel;                 //收货人电话号码，如：0571-81234567
            string receive_mobile = string.IsNullOrEmpty(trade.Mobile) ? trade.Tel : trade.Mobile;  	    //收货人手机号码，如：13312341234

            

            //扩展参数——第二组物流方式
            //物流方式是三个为一组成组出现。若要使用，三个参数都需要填上数据；若不使用，三个参数都需要为空
            //有了第一组物流方式，才能有第二组物流方式，且不能与第一个物流方式中的物流类型相同，
            //即logistics_type="EXPRESS"，那么logistics_type_1就必须在剩下的两个值（POST、EMS）中选择
            string logistics_fee_1 = "";                					//物流费用，即运费。
            string logistics_type_1 = "";               					//物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
            string logistics_payment_1 = "";           					    //物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

            //扩展参数——第三组物流方式
            //物流方式是三个为一组成组出现。若要使用，三个参数都需要填上数据；若不使用，三个参数都需要为空
            //有了第一组物流方式和第二组物流方式，才能有第三组物流方式，且不能与第一组物流方式和第二组物流方式中的物流类型相同，
            //即logistics_type="EXPRESS"、logistics_type_1="EMS"，那么logistics_type_2就只能选择"POST"
            string logistics_fee_2 = "";                					//物流费用，即运费。
            string logistics_type_2 = "";               					//物流类型，三个值可选：EXPRESS（快递）、POST（平邮）、EMS（EMS）
            string logistics_payment_2 = "";            					//物流支付方式，两个值可选：SELLER_PAY（卖家承担运费）、BUYER_PAY（买家承担运费）

            //扩展功能参数——其他
            string buyer_email = "";                    					//默认买家支付宝账号
            string discount =  trade.DisCount.ToString();                    //折扣，是具体的金额，而不是百分比。若要使用打折，请使用负数，并保证小数点最多两位数

            /////////////////////////////////////////////////////////////////////////////////////////////////////

            //构造请求函数，无需修改
            AlipayService aliService = new AlipayService(
                partner,
                seller_email,
                return_url,
                notify_url,
                show_url,
                out_trade_no,
                subject,
                body,
                price,
                logistics_fee,
                logistics_type,
                logistics_payment,
                quantity,
                receive_name,
                receive_address,
                receive_zip,
                receive_phone,
                receive_mobile,
                logistics_fee_1,
                logistics_type_1,
                logistics_payment_1,
                logistics_fee_2,
                logistics_type_2,
                logistics_payment_2,
                buyer_email,
                discount,
                key,
                input_charset,
                sign_type);


            AppendMeta("正在转向支付宝交易平台.....");
            string sHtmlText = aliService.Build_Form();
            return Content(sHtmlText);
            //打印页面
            ViewData["content"] = sHtmlText;
            return View();
        }


        /// <summary>
        /// 功能：支付宝主动通知调用的页面（服务器异步通知页面）
        /// 版本：3.1
        /// 日期：2010-11-24
        /// 说明：
        /// 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
        /// 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
        /// 
        /// ///////////////////页面功能说明///////////////////
        /// 创建该页面文件时，请留心该页面文件中无任何HTML代码及空格。
        /// 该页面不能在本机电脑测试，请到服务器上做测试。请确保互联网上可以访问该页面。
        /// 该页面调试工具请使用写文本函数log_result，该函数已被默认开启
        /// WAIT_BUYER_PAY(表示买家已在支付宝交易管理中产生了交易记录，但没有付款);
        /// WAIT_SELLER_SEND_GOODS(表示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货);
        /// WAIT_BUYER_CONFIRM_GOODS(表示卖家已经发了货，但买家还没有做确认收货的操作);
        /// TRADE_FINISHED(表示买家已经确认收货，这笔交易完成);
        /// 该通知页面主要功能是：防止订单未更新。如果没有收到该页面打印的 success 信息，支付宝会在24小时内按一定的时间策略重发通知
        /// </summary>        
        
        public ActionResult AliPayasSureNotify()
        {
           
            Pay pay = _PayDao.GetById(typeof(AliPayasSurePayModel));

            SortedDictionary<string, string> sArrary = GetRequestPost();
            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的//////////////////////
            AlipayConfig con = new AlipayConfig(_ShopContext, (AliPayasSurePayModel)pay.PayModel);
            string partner = con.Partner;
            string key = con.Key;
            string input_charset = con.Input_charset;
            string sign_type = con.Sign_type;
            string transport = con.Transport;
            //////////////////////////////////////////////////////////////////////////////////////////////

            if (sArrary.Count > 0)//判断是否有带返回参数
            {
                AlipayNotify aliNotify = new AlipayNotify(sArrary, Request.Form["notify_id"], partner, key, input_charset, sign_type, transport);
                string responseTxt = aliNotify.ResponseTxt; //获取远程服务器ATN结果，验证是否是支付宝服务器发来的请求
                string sign = Request.Form["sign"];         //获取支付宝反馈回来的sign结果
                string mysign = aliNotify.Mysign;           //获取通知返回后计算后（验证）的签名结果

                //写日志记录（若要调试，请取消下面两行注释）
                string sWord = "responseTxt=" + responseTxt + "\n notify_url_log:sign=" + Request.Form["sign"] + "&mysign=" + mysign + "\n notify回来的参数：" + aliNotify.PreSignStr;
                AlipayFunction.log_result(Server.MapPath("~/log/" + DateTime.Now.ToString().Replace(":", "")) + ".txt", sWord);

                //判断responsetTxt是否为ture，生成的签名结果mysign与获得的签名结果sign是否一致
                //responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
                //mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
                if (responseTxt == "true" && sign == mysign)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码

                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
                    string trade_no = Request.Form["trade_no"];         //支付宝交易号
                    string order_no = Request.Form["out_trade_no"];     //获取订单号
                    string total_fee = Request.Form["price"];           //获取总金额
                    string subject = Request.Form["subject"];           //商品名称、订单名称
                    string body = Request.Form["body"];                 //商品描述、订单备注、描述
                    string buyer_email = Request.Form["buyer_email"];   //买家支付宝账号
                    string trade_status = Request.Form["trade_status"]; //交易状态
                    string totalsum = Request.QueryString["total_fee"]; //买家支付金额

                    if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")
                    {
                        //该判断表示买家已在支付宝交易管理中产生了交易记录，但没有付款
                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == order_no);
                        if (trade.TradeStatus != (int)TradeStatus.等待付款)
                        {
                            trade.TradeStatus = (int)TradeStatus.等待付款;
                            trade.Modified = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }
                        return Content("success");  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "WAIT_SELLER_SEND_GOODS")
                    {
                        //该判断示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货
                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == order_no);
                        if (trade.TradeStatus != (int)TradeStatus.买家已付款)
                        {
                            trade.TradeStatus = (int)TradeStatus.买家已付款;
                            trade.PayTime = DateTime.Now;
                            trade.Payment = Convert.ToDecimal(totalsum);                            
                            trade.Modified = DateTime.Now;

                            //更改用户积分
                            var usercrypt = _ShopUsersCryptographyDao.Find(x => x.UserId == trade.UserId).First();
                            usercrypt.TotalFee += trade.Payment;
                            usercrypt.Point += trade.TotalPoint;
                            _TradeDao.SaveChanges();
                           
                        }
                       
                        return Content("success");  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "WAIT_BUYER_CONFIRM_GOODS")
                    {//该判断表示卖家已经发了货，但买家还没有做确认收货的操作

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序
                        Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == order_no);
                        if (trade.TradeStatus != (int)TradeStatus.卖家已发货)
                        {
                            trade.TradeStatus = (int)TradeStatus.卖家已发货;
                            trade.Modified = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }

                        return Content("success");  //请不要修改或删除
                    }
                    else if (Request.Form["trade_status"] == "TRADE_FINISHED")
                    {//该判断表示买家已经确认收货，这笔交易完成

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序


                        Trade trade = _TradeDao.FirstOrDefault(x => x.TradeId == order_no);
                        if (trade.TradeStatus != (int)TradeStatus.交易成功)
                        {
                            trade.TradeStatus = (int)TradeStatus.交易成功;
                            trade.EndTime = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }                       

                        return Content("success");  //请不要修改或删除
                    }
                    else
                    {
                        return Content("success");  //其他状态判断。普通即时到帐中，其他状态不用判断，直接打印success。
                    }
                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                else//验证失败
                {
                    return Content("fail");
                }
            }
            else
            {
                return Content("无通知参数");
            }
        }

        /// <summary>
        /// 功能：付完款后跳转的页面（页面跳转同步通知页面）
        /// 版本：3.1
        /// 日期：2010-11-24
        /// 说明：
        /// 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
        /// 该代码仅供学习和研究支付宝接口使用，只是提供一个参考。
        /// 
        /// ///////////////////////页面功能说明///////////////////////
        /// 该页面可在本机电脑测试
        /// 该页面称作“页面跳转同步通知页面”，是由支付宝服务器同步调用，可当作是支付完成后的提示信息页，如“您的某某某订单，多少金额已支付成功”。
        /// 可放入HTML等美化页面的代码和订单交易完成后的数据库更新程序代码
        /// 该页面可以使用ASP.NET开发工具调试，也可以使用写文本函数Log_result进行调试，该函数已被默认关闭
        /// WAIT_SELLER_SEND_GOODS(表示买家已在支付宝交易管理中产生了交易记录且付款成功，但卖家没有发货);
        /// </summary>       
        public ActionResult AliPayAsSureReturn()
        {
            AppendMeta("交易状态");
            SortedDictionary<string, string> sArrary = GetRequestGet();
            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的//////////////////////            
            Pay pay = _PayDao.GetById(typeof(AliPayasSurePayModel));
            AlipayConfig con = new AlipayConfig(_ShopContext, (AliPayasSurePayModel)pay.PayModel);         
            ///////////////////////以下参数是需要设置的相关配置参数，设置后不会更改的//////////////////////
           
            string partner = con.Partner;
            string key = con.Key;
            string input_charset = con.Input_charset;
            string sign_type = con.Sign_type;
            string transport = con.Transport;
            //////////////////////////////////////////////////////////////////////////////////////////////

            if (sArrary.Count > 0)//判断是否有带返回参数
            {
                AlipayNotify aliNotify = new AlipayNotify(sArrary, Request.QueryString["notify_id"], partner, key, input_charset, sign_type, transport);
                string responseTxt = aliNotify.ResponseTxt; //获取远程服务器ATN结果，验证是否是支付宝服务器发来的请求
                string sign = Request.QueryString["sign"];  //获取支付宝反馈回来的sign结果
                string mysign = aliNotify.Mysign;           //获取通知返回后计算后（验证）的签名结果

                //写日志记录（若要调试，请取消下面两行注释）
                //string sWord = "responseTxt=" + responseTxt + "\n return_url_log:sign=" + Request.QueryString["sign"] + "&mysign=" + mysign + "\n return回来的参数：" + aliNotify.PreSignStr;
                //AlipayFunction.log_result(Server.MapPath("log/" + DateTime.Now.ToString().Replace(":", "")) + ".txt",sWord);

                //判断responsetTxt是否为ture，生成的签名结果mysign与获得的签名结果sign是否一致
                //responsetTxt的结果不是true，与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
                //mysign与sign不等，与安全校验码、请求时的参数格式（如：带自定义参数等）、编码格式有关
                 if (responseTxt == "true" && sign == mysign)//验证成功
                {
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    //请在这里加上商户的业务逻辑程序代码

                    //——请根据您的业务逻辑来编写程序（以下代码仅作参考）——
                    //获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表
                    string trade_no = Request.QueryString["trade_no"];              //支付宝交易号                   
                    string order_no = Request.QueryString["out_trade_no"];	        //获取订单号
                    string total_fee = Request.QueryString["price"];	            //获取总金额
                    string subject = Request.QueryString["subject"];                //商品名称、订单名称
                    string body = Request.QueryString["body"];                      //商品描述、订单备注、描述
                    string buyer_email = Request.QueryString["buyer_email"];        //买家支付宝账号
                    string receive_name = Request.QueryString["receive_name"];      //收货人姓名
                    string receive_address = Request.QueryString["receive_address"];//收货人地址
                    string receive_zip = Request.QueryString["receive_zip"];        //收货人邮编
                    string receive_phone = Request.QueryString["receive_phone"];    //收货人电话
                    string receive_mobile = Request.QueryString["receive_mobile"];  //收货人手机
                    string trade_status = Request.QueryString["trade_status"];      //交易状态
                    string totalsum = Request.QueryString["total_fee"];
                    Trade trade = _TradeDao.Find(x => x.TradeId == order_no).First();
                    AppendMeta(string.Format("订单{0}交易状态",trade.TradeId));
                    //打印页面
                    //lbTrade_no.Text = trade_no;
                    //lbOut_trade_no.Text = order_no;
                    //lbTotal_fee.Text = total_fee;
                    //lbSubject.Text = subject;
                    //lbBody.Text = body;
                    //lbBuyer_email.Text = buyer_email;
                    //LbName.Text = receive_name;
                    //LbAddress.Text = receive_address;
                    //LbZip.Text = receive_zip;
                    //LbPhone.Text = receive_phone;
                    //LbMobile.Text = receive_mobile;
                    //lbTrade_status.Text = trade_status;
                    //lbVerify.Text = "验证成功";
                    if (Request.Form["trade_status"] == "WAIT_BUYER_PAY")
                    {
                        //该判断表示买家已在支付宝交易管理中产生了交易记录，但没有付款
                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序                         
                        if (trade.TradeStatus != (int)TradeStatus.等待付款)
                        {
                            trade.TradeStatus = (int)TradeStatus.等待付款;
                            trade.Modified = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }                        
                    }
                    if (Request.QueryString["trade_status"] == "WAIT_SELLER_SEND_GOODS")
                    {
                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序                         
                        if (trade.TradeStatus != (int)TradeStatus.买家已付款)
                        {
                            trade.TradeStatus = (int)TradeStatus.买家已付款;
                            trade.Modified = DateTime.Now;
                            trade.PayTime = DateTime.Now;  
                            trade.Payment = Convert.ToDecimal(totalsum);
                            //更改用户积分
                            var usercrypt = _ShopUsersCryptographyDao.Find(x => x.UserId == trade.UserId).First();
                            usercrypt.TotalFee += trade.Payment;
                            usercrypt.Point += trade.TotalPoint;
                            _TradeDao.SaveChanges();
                        }
                    }                    
                    else if (Request.Form["trade_status"] == "WAIT_BUYER_CONFIRM_GOODS")
                    {//该判断表示卖家已经发了货，但买家还没有做确认收货的操作

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序                     
                        if (trade.TradeStatus != (int)TradeStatus.卖家已发货)
                        {
                            trade.TradeStatus = (int)TradeStatus.卖家已发货;
                            trade.Modified = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }
                        
                    }
                    else if (Request.Form["trade_status"] == "TRADE_FINISHED")
                    {//该判断表示买家已经确认收货，这笔交易完成

                        //判断该笔订单是否在商户网站中已经做过处理（可参考“集成教程”中“3.4返回数据处理”）
                        //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                        //如果有做过处理，不执行商户的业务程序                        
                        if (trade.TradeStatus != (int)TradeStatus.交易成功)
                        {
                            trade.TradeStatus = (int)TradeStatus.交易成功;                           
                            trade.EndTime = DateTime.Now;
                            _TradeDao.SaveChanges();
                        }                       
                    }
                    else
                    {
                        string content = "交易出现问题，请检查。 trade_status = " + Request.QueryString["trade_status"] + "";
                        return Content(content);
                    }
                   
                    //——请根据您的业务逻辑来编写程序（以上代码仅作参考）——

                    return View(trade);
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
                }
                 else//验证失败
                {
                    ViewData["msg"] = "验证失败";
                    return Content(ViewData["msg"].ToString());    
                  
                }
            }
            else
            {
                ViewData["msg"] = "无返回参数";
                return Content(ViewData["msg"].ToString());                  
            }
           
        }

       

        /// <summary>
        /// 获取支付宝POST过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestPost()
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.Form;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.Form[requestItem[i]]);
            }

            return sArray;
        }

        /// <summary>
        /// 获取支付宝GET过来通知消息，并以“参数名=参数值”的形式组成数组
        /// </summary>
        /// <returns>request回来的信息组成的数组</returns>
        public SortedDictionary<string, string> GetRequestGet()
        {
            int i = 0;
            SortedDictionary<string, string> sArray = new SortedDictionary<string, string>();
            NameValueCollection coll;
            //Load Form variables into NameValueCollection variable.
            coll = Request.QueryString;

            // Get names of all forms into a string array.
            String[] requestItem = coll.AllKeys;

            for (i = 0; i < requestItem.Length; i++)
            {
                sArray.Add(requestItem[i], Request.QueryString[requestItem[i]]);
            }

            return sArray;
        }

    }
}
